bitkeeper revision 1.140.1.1 (3e747812JL9EFIy408RAfKRoUWkB7Q)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sun, 16 Mar 2003 13:11:46 +0000 (13:11 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sun, 16 Mar 2003 13:11:46 +0000 (13:11 +0000)
schedule.c, time.c, irq.c, apic.c:
  Fixed TSC sync problem in Xen timer code.

xen/arch/i386/apic.c
xen/arch/i386/irq.c
xen/arch/i386/time.c
xen/common/schedule.c

index e90c17e0c9efa446902df98c74fa1bef80494f6e..ba45f6ff19cc5fdec6cf333d3746188b6cea73bf 100644 (file)
@@ -748,8 +748,10 @@ unsigned int apic_timer_irqs [NR_CPUS];
 void smp_apic_timer_interrupt(struct pt_regs * regs)
 {
     int cpu = smp_processor_id();
+#ifndef NDEBUG
     u32 cc_start, cc_end;
     rdtscl(cc_start);
+#endif
 
     /*
      * the NMI deadlock-detector uses this.
@@ -771,9 +773,11 @@ void smp_apic_timer_interrupt(struct pt_regs * regs)
     if (softirq_pending(cpu))
         do_softirq();
 
+#ifndef NDEBUG
     rdtscl(cc_end);
     if ( (cc_end - cc_start) > (cpu_khz * 100) )
         printk("APIC Long ISR on CPU=%02d %08X -> %08X\n",cpu,cc_start,cc_end);
+#endif
 }
 
 /*
index 7a0d554abfae1a6996b16281b18c41f185effba0..504c7261d417ebaa5946369a7811cc7ebbfea091 100644 (file)
@@ -543,8 +543,10 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
     if ( !action || (!(action->flags & SA_NOPROFILE)) )
     {
         perfc_adda(irq_time, cpu, cc_end - cc_start);
+#ifndef NDEBUG
         if ( (cc_end - cc_start) > (cpu_khz * 100) )
             printk("Long interrupt %08x -> %08x\n", cc_start, cc_end);
+#endif
     }
 
     return 1;
index d03767ef2b3a73ea62571489dec6ace81990c953..a2c2f12bb13d29b0162b013706533930bd28f852 100644 (file)
@@ -12,7 +12,7 @@
  * Environment: Xen Hypervisor
  * Description: modified version of Linux' time.c
  *              implements system and wall clock time.
- *                             based on freebsd's implementation.
+ *              based on freebsd's implementation.
  *
  ****************************************************************************
  * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
@@ -48,7 +48,7 @@
 #define TRC(_x)
 #endif
 
-unsigned long cpu_khz; /* Detected as we calibrate the TSC */
+unsigned long cpu_khz;  /* Detected as we calibrate the TSC */
 unsigned long ticks_per_usec; /* TSC ticks per microsecond. */
 
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
@@ -86,7 +86,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0,
-                                                                 "timer", NULL, NULL};
+                                  "timer", NULL, NULL};
 
 /* ------ Calibrate the TSC ------- 
  * Return processor ticks per second / CALIBRATE_FRAC.
@@ -108,9 +108,9 @@ static unsigned long __init calibrate_tsc(void)
      * terminal count mode), binary count, load 5 * LATCH count, (LSB and MSB)
      * to begin countdown.
      */
-    outb(0xb0, 0x43);                  /* binary, mode 0, LSB/MSB, Ch 2 */
-    outb(CALIBRATE_LATCH & 0xff, 0x42);        /* LSB of count */
-    outb(CALIBRATE_LATCH >> 8, 0x42);  /* MSB of count */
+    outb(0xb0, 0x43);           /* binary, mode 0, LSB/MSB, Ch 2 */
+    outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
+    outb(CALIBRATE_LATCH >> 8, 0x42);   /* MSB of count */
 
     {
         unsigned long startlow, starthigh;
@@ -177,7 +177,7 @@ mktime (unsigned int year, unsigned int mon,
     if (0 >= (int) (mon -= 2)) {   /* 1..12 -> 11,12,1..10 */
         mon += 12;                 /* Puts Feb last since it has leap day */
         year -= 1;
-       }
+    }
     return ((((unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day)+
               year*365 - 719499
         )*24 + hour /* now have hours */
@@ -197,13 +197,13 @@ static unsigned long get_cmos_time(void)
      * Let's hope other operating systems interpret the RTC the same way.
      */
     /* read RTC exactly on falling edge of update flag */
-    for (i = 0 ; i < 1000000 ; i++)    /* may take up to 1 second... */
+    for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
         if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
             break;
-    for (i = 0 ; i < 1000000 ; i++)    /* must try at least 2.228 ms */
+    for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
         if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
             break;
-       do { /* Isn't this overkill ? UIP above should guarantee consistency */
+    do { /* Isn't this overkill ? UIP above should guarantee consistency */
         sec = CMOS_READ(RTC_SECONDS);
         min = CMOS_READ(RTC_MINUTES);
         hour = CMOS_READ(RTC_HOURS);
@@ -215,10 +215,10 @@ static unsigned long get_cmos_time(void)
     {
         BCD_TO_BIN(sec);
         BCD_TO_BIN(min);
-           BCD_TO_BIN(hour);
-           BCD_TO_BIN(day);
-           BCD_TO_BIN(mon);
-           BCD_TO_BIN(year);
+        BCD_TO_BIN(hour);
+        BCD_TO_BIN(day);
+        BCD_TO_BIN(mon);
+        BCD_TO_BIN(year);
     }
     spin_unlock(&rtc_lock);
     if ((year += 1900) < 1970)
@@ -235,23 +235,29 @@ static unsigned long get_cmos_time(void)
  ***************************************************************************/
 
 static spinlock_t stime_lock;
-static u32     st_scale_f;
-static u32     st_scale_i;
-u32                    stime_pcc;       /* cycle counter value at last timer irq */
-s_time_t       stime_now;   /* time in ns at last timer IRQ */
+static u32  st_scale_f;
+static u32  st_scale_i;
+u32         stime_pcc;   /* cycle counter value at last timer irq */
+s_time_t    stime_now;   /* time in ns at last timer IRQ */
 
 static inline s_time_t __get_s_time(void)
 {
-    u32         delta_tsc, low, pcc;
+    s32      delta_tsc;
+    u32      low, pcc;
     u64      delta;
     s_time_t now;
 
-    pcc = stime_pcc;           
+    pcc = stime_pcc;        
     now = stime_now;
 
-    /* only use bottom 32bits of TSC. This should be sufficient */
+    /*
+     * We only use the bottom 32 bits of the TSC. This should be sufficient,
+     * although we take care that TSC on thsi CPU may be lagging the master TSC
+     * slightly. In this case we clamp the TSC difference to a minimum of zero.
+     */
     rdtscl(low);
     delta_tsc = low - pcc;
+    if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
     delta = ((u64)delta_tsc * st_scale_f);
     delta >>= 32;
     delta += ((u64)delta_tsc * st_scale_i);
@@ -273,7 +279,7 @@ s_time_t get_s_time(void)
 /* Wall Clock time */
 static spinlock_t wctime_lock;
 struct timeval    wall_clock_time; /* wall clock time at last update */
-s_time_t             wctime_st;       /* system time at last update */
+s_time_t          wctime_st;       /* system time at last update */
 
 void do_gettimeofday(struct timeval *tv)
 {
@@ -318,7 +324,7 @@ void update_dom_time(shared_info_t *si)
     si->tv_usec      = wall_clock_time.tv_usec;
     si->wc_timestamp = wctime_st;
     si->wc_version++;
-    spin_unlock_irqrestore(&wctime_lock, flags);       
+    spin_unlock_irqrestore(&wctime_lock, flags);    
 
     TRC(printk(" 0x%08X%08X\n", (u32)(wctime_st>>32), (u32)wctime_st));
 }
@@ -371,7 +377,7 @@ static void update_time(unsigned long foo)
 int __init init_xeno_time()
 {
     int      cpu = smp_processor_id();
-    u32             cpu_cycle;  /* time of one cpu cyle in pico-seconds */
+    u32      cpu_cycle;  /* time of one cpu cyle in pico-seconds */
     u64      scale;      /* scale factor  */
 
     spin_lock_init(&stime_lock);
index 5a9a6c96112278115361452ada29d50063b44cba..4fb1dc207d28b5bf7d667388ab4d504437cf94be 100644 (file)
@@ -249,7 +249,6 @@ asmlinkage void schedule(void)
  need_resched_back:
     perfc_incrc(sched_run2);
 
-
     prev = current;
     next = NULL;
 
@@ -262,14 +261,11 @@ asmlinkage void schedule(void)
     /* remove timer  */
     rem_ac_timer(&schedule_data[this_cpu].s_timer);
 
-    /*
-     * deschedule the current domain
-     */
+    /* deschedule the current domain */
 
     ASSERT(!in_interrupt());
     ASSERT(__task_on_runqueue(prev));
 
-
     if (is_idle_task(prev)) 
         goto deschedule_done;
 
@@ -371,11 +367,10 @@ asmlinkage void schedule(void)
     r_time = ((next_prime->evt - next->evt)/next->mcu_advance) + ctx_allow;
 
  sched_done:
-    ASSERT(r_time != 0);
     ASSERT(r_time >= ctx_allow);
 
 #ifndef NDEBUG
-    if ( (r_time==0) || (r_time < ctx_allow)) {
+    if (r_time < ctx_allow) {
         printk("[%02d]: %lx\n", this_cpu, r_time);
         dump_rqueue(&schedule_data[this_cpu].runqueue, "foo");
     }
@@ -393,7 +388,7 @@ asmlinkage void schedule(void)
  timer_redo:
     schedule_data[this_cpu].s_timer.expires  = now + r_time;
     if (add_ac_timer(&schedule_data[this_cpu].s_timer) == 1) {
-        printk("SCHED[%02d]: Shit this shouldn't happen r_time=%lu\n", 
+        printk("SCHED[%02d]: timeout already happened! r_time=%u\n",
                this_cpu, r_time);
         now = NOW();
         goto timer_redo;